Skip to main content

OpenTelemetry Integration

Catalyst-core provides a built-in SDK for OpenTelemetry integration, enabling comprehensive observability through distributed tracing and metrics collection. The SDK simplifies the setup process and provides a unified interface for monitoring your Catalyst applications.


Installation

Install the required OpenTelemetry packages for automatic instrumentation:

npm install @opentelemetry/auto-instrumentations-node @opentelemetry/sdk-node

Quick Setup

Import the OpenTelemetry SDK from catalyst-core:

import Otel from "catalyst-core/otel";

Initialize OpenTelemetry in your preServerInit() function in server/index.js:

const preServerInit = () => {
Otel.init();
};

This provides a quick setup with default configuration and automatic instrumentation.

Configuration

You can customize the OpenTelemetry setup by passing a configuration object to Otel.init():

const preServerInit = () => {
Otel.init({
serviceName: "my-service",
serviceVersion: "1.0.0",
environment: "production",
traceUrl: "http://localhost:4318/v1/traces",
metricUrl: "http://localhost:4318/v1/metrics",
traceHeaders: {
"Authorization": "Bearer your-token"
},
metricHeaders: {
"Authorization": "Bearer your-token"
},
exportIntervalMillis: 5000,
exportTimeoutMillis: 30000
});
};

Configuration Options

OptionTypeDescriptionDefault
serviceNamestringName of your service"catalyst-app"
serviceVersionstringVersion of your service"1.0.0"
environmentstringEnvironment (dev, staging, prod)"development"
traceUrlstringOTLP trace export endpoint"http://localhost:4318/v1/traces"
metricUrlstringOTLP metric export endpoint"http://localhost:4318/v1/metrics"
traceHeadersobjectHeaders for trace export{}
metricHeadersobjectHeaders for metric export{}
exportIntervalMillisnumberMetric export interval in ms10000
exportTimeoutMillisnumberExport timeout in ms10000

Manual Setup

For more control over the OpenTelemetry configuration, you can set it up manually using the Node SDK:

import { NodeSDK } from '@opentelemetry/sdk-node';
import { Resource } from '@opentelemetry/resources';
import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions';
import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-otlp-http';

const preServerInit = () => {
const sdk = new NodeSDK({
resource: new Resource({
[ATTR_SERVICE_NAME]: 'catalyst-app',
}),
spanProcessor: new SimpleSpanProcessor(new OTLPTraceExporter()),
});

sdk.start();
};

Testing Your Instrumentation

You need an OpenTelemetry collector with a compatible backend to test OpenTelemetry traces locally.

Setting Up a Local OpenTelemetry Collector

The OpenTelemetry Collector acts as a middleman between your application and observability backends. It receives, processes, and exports telemetry data. Here are several options for local testing:

Option 1: Docker Compose with Jaeger and Prometheus Backend

Create a docker-compose.yml file for a complete observability stack:

version: '3.8'
services:
# Jaeger
jaeger:
image: jaegertracing/all-in-one:latest
ports:
- "16686:16686"
- "14268:14268"
environment:
- COLLECTOR_OTLP_ENABLED=true

# OpenTelemetry Collector
otel-collector:
image: otel/opentelemetry-collector-contrib:latest
command: ["--config=/etc/otel-collector-config.yaml"]
volumes:
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
ports:
- "4317:4317" # OTLP gRPC receiver
- "4318:4318" # OTLP HTTP receiver
depends_on:
- jaeger

# Prometheus
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yaml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"

Create an otel-collector-config.yaml file:

receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318

processors:
batch:

exporters:
jaeger:
endpoint: jaeger:14250
tls:
insecure: true
prometheus:
endpoint: "0.0.0.0:8889"

service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [jaeger]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [prometheus]

Create a prometheus.yaml file

scrape_configs:
- job_name: 'otel-collector'
static_configs:
- targets: ['otel-collector:8889']
scrape_interval: 10s
metrics_path: /metrics

Start the stack: docker-compose up -d

Access Jaeger UI at: http://localhost:16686 Access Prometheus UI at: http://localhost:9090

You can also set up a custom Grafana instance linking to Prometheus for advanced dashboards and alerting For more details see: Grafana

Option 2: Console Exporter (Development Only)

For quick debugging without external dependencies, use the console exporter:

import { NodeSDK } from '@opentelemetry/sdk-node';
import { ConsoleSpanExporter } from '@opentelemetry/sdk-trace-node';
import { Resource } from '@opentelemetry/resources';
import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions';

const preServerInit = () => {
const sdk = new NodeSDK({
resource: new Resource({
[ATTR_SERVICE_NAME]: 'catalyst-app-debug',
}),
traceExporter: new ConsoleSpanExporter(),
});

sdk.start();
};

Compatible Backends

Popular observability backends that work with OpenTelemetry:

  • Jaeger: Open-source distributed tracing platform
  • Zipkin: Distributed tracing system
  • Grafana Cloud: Managed observability platform
  • New Relic: Full-stack observability
  • Datadog: Cloud monitoring platform
  • Honeycomb: Observability for complex systems
  • Lightstep: Distributed tracing and performance monitoring

Verifying Your Setup

  1. Start your observability backend
  2. Run your Catalyst application with OpenTelemetry enabled
  3. Make some requests to your application
  4. Check your backend's UI for traces and metrics

For Jaeger, visit http://localhost:16686 and select your service from the dropdown to view traces.